package http;

import core.ByteBuf;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpRequest extends HttpMessage{
    public String uri="";
    public Map<String, Object> param=new HashMap<>();
    public String method="";

    public int parse(byte[] bytes) {

        if(getHttpLength(bytes,charset) < 0) return -1;

        String data=new String(bytes,charset);//StandardCharsets.ISO_8859_1

        data=clearMessage(data);

        int posFirstLine=data.indexOf(newLine);
        if (posFirstLine!=-1){
            if (!parseFirstLine(data.substring(0,posFirstLine))) return -1;
        }
        else {
            return posFirstLine;
        }

        String strHeader,strContent;
        int posHeader=data.indexOf(newLine+newLine);
        if (posHeader==-1){
            strHeader=data;
            strContent="";
        }
        else {
            strHeader=data.substring(0,posHeader);
            strContent=data.substring(posHeader+2*newLine.length());
        }
        getHeaderField(strHeader.substring(posFirstLine+newLine.length()),this.header);

        if (checkNoContent(data)) return 0;

        return parseContent(this.header,strContent,charset,byteBuf);
    }

    public boolean parseFirstLine(String firstLine) {

        int posMethod=firstLine.indexOf(" ");
        if (posMethod==-1) return false;

        this.method=firstLine.substring(0,posMethod);
        //System.out.println(method);

        int posUri=firstLine.indexOf(" HTTP/",posMethod);
        if (posUri==-1) return false;

        this.uri=firstLine.substring(posMethod+1,posUri);
        //System.out.println(uri);

        parseParam(this.uri);

        this.httpVersion=firstLine.substring(posUri+" HTTP/".length());
        //System.out.println(httpVersion);

        return true;
    }

    public int parseParam(String uri) {

        if (uri.contains("?")){
            String paramString=uri.substring(uri.indexOf("?"));
            String[] paras=paramString.split("&");
            for (String para:paras
                 ) {
                int posEqual=para.indexOf("=");
                param.put(para.substring(0,posEqual),para.substring(posEqual+1));
            }
            return paras.length;
        }

        return 0;
    }

    public String parseForm(String body,ByteBuf buf){

        String fileName="";
        String contentType=getHeader("content-type");
        if (contentType.startsWith("multipart/form-data")) {
            String boundary = contentType.substring(contentType.indexOf('=') + 1);
            System.out.println(boundary);
            String[] formData = body.split(boundary);
            for (String item:formData) {
                int pos=item.indexOf(newLine+newLine);
                if (pos==-1) continue;
                String itemHeader=item.substring(newLine.length(),pos);
                String itemBody=item.substring(pos+2*newLine.length(),item.lastIndexOf(newLine)/*去除最后的回车换行*/);
                if (itemHeader.contains("filename")) { // 遇到文件了
                    String[] lines=itemHeader.split(newLine);
                    fileName =itemHeader.substring(lines[0].indexOf("filename=\"") + "filename=\"".length(), lines[0].lastIndexOf('"'));
                    fileName=new String(fileName.getBytes(charset),StandardCharsets.UTF_8);
                    System.out.println(fileName);
                    if (buf!=null) buf.put(itemBody.getBytes(charset));
                }
                else {
                    // 普通参数
                    String paramName = itemHeader.substring(itemHeader.indexOf('"') + 1, itemHeader.lastIndexOf('"'));
                    String paramValue = itemBody;
                    System.out.println(paramName+": "+paramValue);
                    param.put(paramName, paramValue);
                }

            }
        }

        return fileName;
    }
    
    public byte[] buildMessage() {
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(this.method)
                .append(" ")
                .append(this.uri)
                .append(" HTTP/")
                .append(httpVersion)
                .append(newLine);

        header.forEach((key, value) -> stringBuilder.append(key)
                .append(": ")
                .append(value.get(value.size() - 1))
                .append(newLine));

        stringBuilder.append(newLine);
        System.out.println(stringBuilder);

        ByteBuf buf=new ByteBuf();
        buf.put(stringBuilder.toString().getBytes(charset));

        if (byteBuf.getCanReadSize()>0) {
            byte[] bytes = byteBuf.get();
            buf.put(bytes);
        }

        return buf.get();
    }

}
